package university;
import university.exceptions.*;

import java.io.*;
import java.util.*;

/**
 * Class that describes academical group
 * @author anatolii.bondarenko
 */
class Group implements Serializable{
    private String groupCode;
    private int groupNumber;
    private int course;
    private String groupName;
    transient private List<Student> students;
    private boolean graduated;

    /**
     * Details of group
     * @param c in number of course
     * @param num is group number
     * @param grcode is code of group(group speciality)
     * @param st is the list of students in group
     */
    public Group(int c, int num, String grcode, List<Student> st) throws InvalidGroupCourseException, InvalidGroupNumberException, EmptyStringException, ListEmptyException {
		course = c;
		groupNumber = num;
		groupCode = grcode;
		groupName = grcode + c + num;
		students = new ArrayList<Student>(st);
        if (c > 6 || c < 1){
            throw new InvalidGroupCourseException("Cource cannot be lower than 1 or higher than 6");
        }
        if (num < 1){
            throw new InvalidGroupNumberException("Group number must be a positive integer");
        }
        if (grcode.trim() == ""){
            throw new EmptyStringException("Group code cannot be empty or consist only of whitespaces");
        }
        if (st.size() == 0){
            throw new ListEmptyException("Group cannot be empty");
        }
	}

    /**
     * Gets group name
     * @return group name
     */
    public String getGroupName(){
		return groupName;
	}

    /**
     * Gets list of student in group
     * @return list of students
     */
    public List<Student> getListOfStudents(){
		return students;
	}

    /**
     * Group name must be changed according to year of study
     */
    private void setGroupName(){
		groupName = groupCode + course + groupNumber;
	}

    /**
     * Adds student to group
     * @param s is student that will be added
     */
	public void addStudentToGroup(Student s) throws CannotAddToListException{
		if (s.isResigned() == true){
            throw new CannotAddToListException("Cannot add resigned students to group");
        }
        students.add(s);
	}

    /**
     * Removes student from group
     * @param s is student that will be removed
     */
    public void removeStudentFromGroup(Student s) throws ListEmptyException, NoElementInListException{
		if (students.contains(s)==false){
            throw new NoElementInListException("No such Student in this group");
        }
        students.remove(s);
        if (students.size() == 0){
            throw new ListEmptyException("Group cannot be empty");
        }
	}

    /**
     * After a year of study group goes to next course
     */
    public void raiseCourse(){
		for(Student s:students){
            s.resetStudentResult();
        }
        course++;
		if (course > 6){
			graduated = true;
			course--;
			System.out.print("This group was graduated");
		}
		setGroupName();
	}

    /**
     * Checks if group is graduated
     * @return true if graduated.
     */
    public boolean isGraduated(){
		return graduated; 
	}
	

    public static void main(String[] args)throws Exception{
        //in this file List with available groups will be stored
        File groupsList = new File("groupsList.dat");
        groupsList.createNewFile();
        //in this file group names will be stored
        File groups = new File("groups.dat");
        groups.createNewFile();
        //create 1 member dummy list of students to prevent listEmptyException
        Student st = new Student("a", "b", 1988, 1, 1, 0);
        List<Student> students1 = new ArrayList<Student>(0);
        students1.add(st);
        //create list of groups and write them to file
        List<Group> groupList = new ArrayList<Group>(0);
        Group group;
        for (int i = 1; i <= 6; i++){
            for (int j = 1; j<=2; j++){
                group = new Group(i,j,"DZ", students1);
                groupList.add(group);
            }
        }

        try {
            FileOutputStream fs = new FileOutputStream("groupsList.dat");
            ObjectOutputStream os =new ObjectOutputStream(fs);
            os. writeObject(groupList);
            os.flush();
            os.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }


        List<Group> groupList1 = null;
        try {
            FileInputStream fis = new FileInputStream("groupsList.dat");
            ObjectInputStream ois =new ObjectInputStream(fis);
            groupList1 = (List<Group>) ois. readObject();
            ois.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        //write group names to groups.dat file
        PrintWriter pw =new PrintWriter(groups);
        for (Group i:groupList1){
            pw.println(i.getGroupName());
            pw.flush();
        }
        pw.close();
    }
}
